#include "common.h"

extern volatile int frametick;

Config::Config()
{
        direction = DIR_LEFT;
        console_fg_color = makecol(50, 50, 50);
        console_bg_color = makecol(128, 148, 138);
        inventory_fg_color = makecol(0, 0, 50);
        inventory_bg_color = makecol(50, 50, 0);
        player_x = SCREEN_W/2 - 16;
        player_y = SCREEN_H/2 - 26;
        screenxy_to_mapxy(player_x+32, player_y+48, player_mapx, player_mapy);
        player_mapx /= 64;
        player_mapy /= 32;
        cur_x = IN_BOX_MINX;
        cur_y = IN_BOX_MINY;
        walktick = frametick;
}

void Config::fresh_position(short x, short y)
{
        if (frametick > walktick && frametick - walktick < 5)
                return;

        if (frametick < walktick && walktick - frametick < 5)
                return;

        if (player_mapx != x)
                cur_x += (x - player_mapx) > 0 ? 1 : -1;
        if (player_mapy != y)
                cur_y += (y - player_mapy) > 0 ? 1 : -1;

        if ((x-player_mapx)<(y-player_mapy))
                direction = DIR_LEFT;
        else
                direction = DIR_RIGHT;

        if (cur_x < IN_BOX_MINX)
                cur_x = IN_BOX_MINX;
        if (cur_x > IN_BOX_MAXX)
                cur_x = IN_BOX_MAXX;
        if (cur_y < IN_BOX_MINX)
                cur_y = IN_BOX_MINX;
        if (cur_y > IN_BOX_MAXY)
                cur_y = IN_BOX_MAXY;


        walktick = frametick;
}

void screenxy_to_mapxy(short sx, short sy, short &mx, short &my)
{
        sx -= screen_startx;
        sy -= screen_starty;
        mx = sx + 2*sy;
        my = sy - sx/2;
}

void mapxy_to_screenxy(short mx, short my, short &sx, short &sy)
{
        my /= 2;
        mx -= INST(Config).cur_x * 64;
        my -= INST(Config).cur_y * 32;
        sy = (mx + 2*my)/4 + screen_starty;
        sx = (mx - 2*my)/2 + screen_startx;
}

string &trim(string &str)
{
        str.erase(0, str.find_first_not_of(" \t\r\n"));
        str.erase(str.find_last_not_of(" \t\r\n") + 1);
        return str;
}

string &replaceAll(string s, const string &find, const string &repl)
{
        string::size_type found;
        string::size_type start = 0;

        while ((found = s.find(find, start)) != string::npos) {
                s.replace(found, find.length(), repl);
                start = found + repl.length();
        }

        return s;
}

void split(vector<string> &ret, const char *buf, char sep)
{
        if (buf == NULL || *buf == '\0')
                return ;

        int state = 0;
        const char *s = buf;
        const char *e = buf;
        while (state != 2) {
                if (state == 0) {
                        if (*e == sep) {
                                ++s;
                                ++e;
                        } else if (*e == '\0') {
                                state = 2;
                        } else {
                                state = 1;
                                ++e;
                        }
                } else if (state == 1) {
                        if (*e == sep) {
                                ret.push_back(string(s, e));
                                state = 0;
                                s = ++e;
                        } else if (*e == '\0') {
                                ret.push_back(string(s, e));
                                state = 2;
                        } else {
                                ++e;
                        }
                }
        }
}

void masked_blit(BITMAP *source, BITMAP *dest, const Rect &pos)
{
        masked_blit(source, dest, 0, 0, pos.x, pos.y, pos.w, pos.h);
}

GifAnimation::GifAnimation (const char *filename)
{
        m_cur = 0;
        m_loops = 0;
        m_nframe = algif_load_animation(filename, &m_frames, &m_durations);
        if (m_nframe  == 0)
                throw LoadGifFailed();
}

GifAnimation::~GifAnimation()
{
        for (int i = 0; i < m_nframe; ++i) {
                destroy_bitmap(m_frames[i]);
        }
        free (m_frames);
        free (m_durations);
}

bool  GifAnimation::NextFrame()
{
        if (++m_cur == m_nframe) {
                m_cur = 0;
                if (m_loops == 0) {
                        return false;
                } else {
                        --m_loops;
                        return true;
                }
        }

        return true;
}
